<?xml version="1.0" encoding="UTF-8"?>

<!-- *** DO NOT USE AUTO FORMAT / tidy *** -->

<!DOCTYPE xsl:stylesheet [
<!ENTITY endl "<xsl:text>&#xa;</xsl:text>">
]>

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:func="http://exslt.org/functions"
    xmlns:date="http://exslt.org/dates-and-times"
    xmlns:rs="http://www.ribbonsoft.com"
    xmlns:str="http://exslt.org/strings"
    xmlns:com="http://exslt.org/common"
    extension-element-prefixes="func date str">

<xsl:include href="query.xsl" />
<xsl:include href="replace.xsl"/>

<xsl:output method="text" />
<xsl:param name="scope"/>
<xsl:param name="mode"/>
<xsl:param name="cwd"/>
<xsl:param name="sharedPointerSupport" select="false()"/>
<xsl:param name="spsSuffix">
    <xsl:choose>
    <xsl:when test="$sharedPointerSupport">
        <xsl:value-of select="'SharedPointerSupport'"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="''"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>
<xsl:param name="spsPointer">
    <xsl:choose>
    <xsl:when test="$sharedPointerSupport">
        <xsl:value-of select="'Pointer'"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="''"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>
<xsl:param name="name" select="/unit/class[@isScriptable = 'true']/@name" />
<xsl:param name="ecmaName" select="rs:toEcmaName($name)" />
<xsl:param name="ecmaShellName" select="rs:toEcmaShellName($name)" />
<xsl:param name="isCopyable" select="/unit/class/@isCopyable='true'" />
<xsl:param name="isQObject" select="/unit/class/@isQObject='true'" />
<xsl:param name="isAbstract" select="/unit/class/@isAbstract='true'" />
<xsl:param name="hasStreamOperator" select="/unit/class/@hasStreamOperator='true'" />
<xsl:param name="prefix">
    <xsl:choose>
    <xsl:when test="$mode='h'">
        <xsl:value-of select="''"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="concat(rs:toEcmaName(/unit/class[@isScriptable = 'true']/@name), '::')"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>
<xsl:param name="static">
    <xsl:choose>
    <xsl:when test="$mode='h'">
        <xsl:value-of select="'static '"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="''"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>
<xsl:param name="hasShell">
    <!--
    <xsl:value-of select="boolean(/unit/class/method[@isVirtual='true'])"/>
    -->
    <xsl:value-of select="boolean(/unit/class[@isScriptable = 'true' and @hasShell = 'true'])"/>
</xsl:param>
<xsl:param name="nameOrShellName">
    <xsl:choose>
    <xsl:when test="$hasShell='true'">
        <xsl:value-of select="$ecmaShellName"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="$name"/>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>
<xsl:param name="isShell">
    <xsl:value-of select="'false'"/>
</xsl:param>
<xsl:param name="ownership">
    <xsl:choose>
    <xsl:when test="$name='RMainWindowQt'">
      <xsl:text>QScriptEngine::QtOwnership</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <!--
      <xsl:text>QScriptEngine::AutoOwnership</xsl:text>
      -->
      <xsl:text>QScriptEngine::QtOwnership</xsl:text>
    </xsl:otherwise>
    </xsl:choose>
</xsl:param>


<!--
<xsl:key name="metatype" match="//arg/@typeName" use="." />
-->

<xsl:template match="/">
    <xsl:apply-templates />
</xsl:template>

<xsl:template match="unit">
    <xsl:apply-templates select="class[@isScriptable = 'true']"/>
</xsl:template>

<xsl:template match="class">

    <!--
    <xsl:variable name="name" select="@name" />
    <xsl:variable name="ecmaName" select="rs:toEcmaName($name)" />
    -->
    <xsl:variable name="uName" select="rs:toUppercase($name)" />
    <xsl:variable name="uEcmaName" select="rs:toUppercase($ecmaName)" />
    <!--
    <xsl:variable name="isCopyable" select="@isCopyable = 'true'" />
    <xsl:variable name="hasStreamOperator" select="@hasStreamOperator = 'true'" />
    <xsl:variable name="isAbstract" select="@isAbstract = 'true'" />
    -->
    <xsl:variable name="isQObject" select="@isQObject = 'true'" />
    <xsl:variable name="hasShell" select="@hasShell = 'true'" />
    <xsl:variable name="isScriptable" select="@isScriptable = 'true'" />

    <!--
    <xsl:message>class:<xsl:value-of select="$name" /></xsl:message>
    <xsl:message>isCopyable:<xsl:value-of select="$isCopyable" /></xsl:message>
    <xsl:message>isQObject:<xsl:value-of select="$isQObject" /></xsl:message>
    <xsl:message>isAbstract:<xsl:value-of select="$isAbstract" /></xsl:message>
    <xsl:message>isScriptable:<xsl:value-of select="$isScriptable" /></xsl:message>
    -->

    <xsl:if test="$isCopyable">
        <xsl:if test="$isQObject or $isAbstract">
            <xsl:message terminate="yes">
                Copyable objects may not be QObjects or abstract.
            </xsl:message>
        </xsl:if>
    </xsl:if>

    <xsl:text>// ***** AUTOGENERATED CODE, DO NOT EDIT *****</xsl:text>
    <!--
    // ***** <xsl:value-of select="date:format-date(date:date-time(),'yyyy-MM-dd HH:mm:ss')" />
    -->
    <xsl:choose>
        <xsl:when test="$isCopyable">
            // ***** This class is copyable.
        </xsl:when>
        <xsl:otherwise>
            // ***** This class is not copyable.
        </xsl:otherwise>
    </xsl:choose>

    <xsl:choose>
      <xsl:when test="$mode='h'">
        #ifndef <xsl:value-of select="$uEcmaName" />_H
        #define <xsl:value-of select="$uEcmaName" />_H

        #include "ecmaapi_global.h"

        #include &lt;QScriptEngine&gt;
        #include &lt;QScriptValue&gt;
        #include &lt;QScriptContextInfo&gt;
        #include &lt;QDebug&gt;

        <xsl:choose>
            <xsl:when test="@typedef">
                <xsl:if test="contains($name, 'Pointer')">
                    #include "<xsl:value-of select="concat(rs:replace($name, 'Pointer', ''), '.h')"/>"
                </xsl:if>

                typedef <xsl:value-of select="@typedef" /><xsl:text> </xsl:text><xsl:value-of select="$name" />;
            </xsl:when>
            <xsl:otherwise>
                #include &quot;<xsl:value-of select="$nameOrShellName" />.h&quot;
            </xsl:otherwise>
        </xsl:choose>

        <xsl:if test="$sharedPointerSupport">
            typedef QSharedPointer&lt;<xsl:value-of select="$name"/>&gt; <xsl:value-of select="$name"/>Pointer;
        </xsl:if>

        /**
         * \ingroup scripting_ecmaapi
         */
        class
        <xsl:if test="$scope='src'">
        QCADECMAAPI_EXPORT
        </xsl:if>
        <xsl:value-of select="$ecmaName" /> {

        public:
      </xsl:when>
      <xsl:otherwise>
        #include "<xsl:value-of select="$ecmaName" />.h"
        #include "RMetaTypes.h"
        #include "../REcmaHelper.h"

        // forwards declarations mapped to includes
        <xsl:for-each select="../class_decl">
            <xsl:choose>
            <xsl:when test="starts-with(@name, 'R')">
                #include "<xsl:value-of select="@name" />.h"
            </xsl:when>
            <xsl:otherwise>
                #include &lt;<xsl:value-of select="@name" />&gt;
            </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
            
        // includes for base ecma wrapper classes
        <xsl:for-each select="/unit/class/baseClass">
          <xsl:if test="starts-with(@name , 'R')">
            <xsl:variable name="name">
              <xsl:choose>
                <xsl:when test="contains(@name , '&lt;')">
                  <xsl:value-of select="substring-before(@name,'&lt;')"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:value-of select="@name"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:variable>
            <xsl:choose>
                <xsl:when test="$sharedPointerSupport">
                  #include "<xsl:value-of select="concat('REcmaSharedPointer', substring($name,2))"/>.h"
                </xsl:when>
                <xsl:otherwise>
                  #include "<xsl:value-of select="concat('REcma', substring($name,2))"/>.h"
                </xsl:otherwise>
            </xsl:choose>
          </xsl:if>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>

    <xsl:call-template name="init" />

    <xsl:choose>
        <!--
        <xsl:when test="$isAbstract or not(/unit/class/constructor)">
        -->
        <xsl:when test="$isAbstract and not($hasShell)">
            <xsl:call-template name="createAbstract" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:call-template name="create" />
        </xsl:otherwise>
    </xsl:choose>

    <!--
    // <xsl:value-of select="$name"/>conversion function for class self (used by inheriting ECMA classes):
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>get<xsl:value-of select="rs:toFunctionName($name)"/>(QScriptContext *context,
        QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        {
            <xsl:value-of select="$name"/>* cppResult =
                qscriptvalue_cast&lt;<xsl:value-of select="$name"/>*&gt; (context->thisObject());
            QScriptValue result = qScriptValueFromValue(engine, cppResult);
            return result;
        }
        </xsl:otherwise>
    </xsl:choose>
    -->

    // conversion functions for base classes:
    <xsl:call-template name="baseClassConversion">
        <xsl:with-param name="baseClassNodes" select="./baseClass[@specifier='public']"/>
    </xsl:call-template>

    // returns class name:
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>getClassName(QScriptContext *context, QScriptEngine *engine) 
        <xsl:choose>
            <xsl:when test="$mode='h'">
                <xsl:text>;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
    {
        return qScriptValueFromValue(engine, QString("<xsl:value-of select="$name"/>"));
    }
    </xsl:otherwise>
    </xsl:choose>

    // returns all base classes (in case of multiple inheritance):
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>getBaseClasses(QScriptContext *context, QScriptEngine *engine) 
        <xsl:choose>
            <xsl:when test="$mode='h'">
                <xsl:text>;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
    {
        QStringList list;
        <xsl:call-template name="baseClassNames">
            <xsl:with-param name="baseClassNodes" select="/unit/class/baseClass[@specifier='public']"/>
        </xsl:call-template>

        return qScriptValueFromSequence(engine, list);
    }
    </xsl:otherwise>
    </xsl:choose>
    
    <xsl:for-each select="baseClass[position() != 1 and @specifier='public']">
      <xsl:if test="starts-with(@name , 'R') and rs:isClassScriptable(@name)">
        // properties of secondary base class <xsl:value-of select="@name"/>:
        <xsl:apply-templates select="document(rs:getXmlFile(@name))/unit/class/property">
            <xsl:with-param name="overrideClassName" select="$name"/>
        </xsl:apply-templates>

        // methods of secondary base class <xsl:value-of select="@name"/>:
        <xsl:apply-templates select="document(rs:getXmlFile(@name))/unit/class/method[@specifier='public']">
            <xsl:with-param name="overrideClassName" select="$name"/>
            <!--
            <xsl:with-param name="baseClassName" select="@name"/>
            -->
        </xsl:apply-templates>
      </xsl:if>
    </xsl:for-each>

    // properties:
    <xsl:apply-templates select="property" />

    // public methods:
    <xsl:apply-templates select="method[@specifier='public']" />

    <xsl:call-template name="toString" />
    <xsl:if test="$isCopyable">
      <xsl:call-template name="copy" />
    </xsl:if>
    <xsl:call-template name="destroy" />
    <xsl:call-template name="getSelf" />
    <xsl:call-template name="getSelfShell" />
    <xsl:if test="$sharedPointerSupport">
      <xsl:call-template name="data" />
      <xsl:call-template name="isNull" />
    </xsl:if>
    <!--
    <xsl:call-template name="throwError" />
    -->
    <xsl:if test="not($isCopyable) and not($isAbstract) and $isQObject">
        <xsl:call-template name="fromScriptValue" />
        <xsl:call-template name="toScriptValue" />
    </xsl:if>

    <xsl:apply-templates select="enum" />

    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>};</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>

<!-- 
    <xsl:if test="$isCopyable">
        Q_DECLARE_METATYPE(
        <xsl:value-of select="$name" />
        )
    </xsl:if>
    Q_DECLARE_METATYPE(
    <xsl:value-of select="$name" />
    *)
    <xsl:if test="/unit/class/baseClass">
        Q_DECLARE_METATYPE(
        <xsl:value-of select="/unit/class/baseClass/@name" />
        *)
    </xsl:if>
    <xsl:for-each
        select="//arg/@typeName[generate-id()=generate-id(key('metatype',.))]">
        <xsl:if test=". != $name and . != concat($name,'*'
          and . != concat(/unit/class/baseClass/@name, '*'))
          and not(rs:isStandardType(.))">
            Q_DECLARE_METATYPE(
            <xsl:value-of select="." />
            )
        </xsl:if>
    </xsl:for-each>
    -->
    <xsl:choose>
    <xsl:when test="$mode='h'">
    #endif
    </xsl:when>
    <xsl:otherwise>
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>



<xsl:template name="baseClassNames">
    <xsl:param name="baseClassNodes" select="com:node-set()"/>

    <xsl:for-each select="$baseClassNodes">
        list.append("<xsl:value-of select="./@name"/>");
    </xsl:for-each>

    <xsl:for-each select="$baseClassNodes">
        <xsl:call-template name="baseClassNames">
            <xsl:with-param name="baseClassNodes" select="document(rs:getXmlFile(@name))/unit/class/baseClass[@specifier='public']"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>


<xsl:template name="baseClassConversion">
    <xsl:param name="baseClassNodes" select="com:node-set()"/>

    <xsl:for-each select="$baseClassNodes">
      <xsl:if test="not(contains(rs:toFunctionName(@name), '::'))">
        <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>get<xsl:value-of select="rs:toFunctionName(@name)"/>(QScriptContext *context,
            QScriptEngine *engine)
        <xsl:choose>
            <xsl:when test="$mode='h'">
                <xsl:text>;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
            {
                <xsl:value-of select="@name"/>* cppResult =
                    qscriptvalue_cast&lt;<xsl:value-of select="$name"/>*&gt; (context->thisObject());
                QScriptValue result = qScriptValueFromValue(engine, cppResult);
                return result;
            }
            </xsl:otherwise>
        </xsl:choose>
      </xsl:if>
    </xsl:for-each>

    <xsl:for-each select="$baseClassNodes">
        <xsl:call-template name="baseClassConversion">
            <xsl:with-param name="baseClassNodes" select="document(rs:getXmlFile(@name))/unit/class/baseClass[@specifier='public']"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>



<xsl:template name="baseClassConversionProperties">
    <xsl:param name="baseClassNodes" select="com:node-set()"/>

    <xsl:for-each select="$baseClassNodes">
      <xsl:if test="not(contains(rs:toFunctionName(@name), '::'))">
        // conversion for base class <xsl:value-of select="@name"/>
        REcmaHelper::registerFunction(&amp;engine, proto, get<xsl:value-of select="rs:toFunctionName(@name)"/>, "get<xsl:value-of select="rs:toFunctionName(@name)"/>");
        <!--
        fun = engine.newFunction();
        fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
        proto->setProperty("get<xsl:value-of select="rs:toFunctionName(@name)"/>", fun,
            QScriptValue::SkipInEnumeration);
        -->
      </xsl:if>
    </xsl:for-each>

    <xsl:for-each select="$baseClassNodes">
        <xsl:call-template name="baseClassConversionProperties">
            <xsl:with-param name="baseClassNodes" select="document(rs:getXmlFile(@name))/unit/class/baseClass[@specifier='public']"/>
        </xsl:call-template>
    </xsl:for-each>
</xsl:template>



<xsl:template match="arg" mode="metatype">
    <xsl:choose>
    <xsl:when test="$mode='h'">
    Q_DECLARE_METATYPE(
    <xsl:value-of select="@typeName" />
    )
    </xsl:when>
    </xsl:choose>
</xsl:template>


<xsl:template name="init">
    <xsl:value-of select="$static"/> void <xsl:value-of select="$prefix"/>initEcma(QScriptEngine&amp; engine, QScriptValue* proto 
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>=NULL</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>
    ) 
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {

    bool protoCreated = false;
    if(proto == NULL){
        proto = new QScriptValue(engine.newVariant(qVariantFromValue(
                (<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer"/>*) 0)));
        protoCreated = true;
    }

    <xsl:if test="baseClass">
        // primary base class <xsl:value-of select="baseClass[1]/@name"/>:
        <xsl:choose>
          <xsl:when test="$sharedPointerSupport">
            proto->setPrototype(engine.defaultPrototype(
            qMetaTypeId&lt;<xsl:value-of select="baseClass[1]/@name" /><xsl:value-of select="$spsPointer"/>&gt;()));
          </xsl:when>
          <xsl:otherwise>
            QScriptValue dpt = engine.defaultPrototype(
                qMetaTypeId&lt;<xsl:value-of select="baseClass[1]/@name" />*&gt;());

            if (dpt.isValid()) {
                proto->setPrototype(dpt);
            }
          </xsl:otherwise>
        </xsl:choose>
        /*
        <xsl:for-each select="baseClass[position() != 1]">
          <xsl:if test="starts-with(@name , 'R') and rs:isClassScriptable(@name)">
            <xsl:value-of select="concat('REcma', substring(@name,2))"/>::initEcma(engine, proto);
          </xsl:if>
        </xsl:for-each>
        */
    </xsl:if>

    QScriptValue fun;

    // toString:
    REcmaHelper::registerFunction(&amp;engine, proto, toString, "toString");
    <!--
    fun = engine.newFunction(toString);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("toString", fun,
       QScriptValue::SkipInEnumeration);
    -->

    <xsl:if test="$isCopyable">
    // copy:
    REcmaHelper::registerFunction(&amp;engine, proto, copy, "copy");
    <!--
    fun = engine.newFunction(copy);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("copy", fun,
       QScriptValue::SkipInEnumeration);
    -->
    </xsl:if>
        
    <xsl:if test="$sharedPointerSupport">
        // shared pointer support:
        REcmaHelper::registerFunction(&amp;engine, proto, data, "data");
        <!--
        fun = engine.newFunction(data);
        fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
        proto->setProperty("data", fun,
           QScriptValue::SkipInEnumeration);
        -->

        REcmaHelper::registerFunction(&amp;engine, proto, isNull, "isNull");
        <!--
        fun = engine.newFunction(isNull);
        fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
        proto->setProperty("isNull", fun,
           QScriptValue::SkipInEnumeration);
        -->
    </xsl:if>

    // destroy:
    REcmaHelper::registerFunction(&amp;engine, proto, destroy, "destroy");
    <!--
    fun = engine.newFunction(destroy);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("destroy", fun,
       QScriptValue::SkipInEnumeration);
    -->

    <xsl:call-template name="baseClassConversionProperties">
        <xsl:with-param name="baseClassNodes" select="baseClass[@specifier='public']"/>
    </xsl:call-template>

    <!--
    // conversion to this class (ECMA inheritance):
    fun = engine.newFunction(get<xsl:value-of select="$name"/>);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("get<xsl:value-of select="$name"/>", fun, 
        QScriptValue::SkipInEnumeration);
    -->

    // get class name
    REcmaHelper::registerFunction(&amp;engine, proto, getClassName, "getClassName");
    <!--
    fun = engine.newFunction(getClassName);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("getClassName", fun, 
        QScriptValue::SkipInEnumeration);
    -->

    // conversion to all base classes (multiple inheritance):
    REcmaHelper::registerFunction(&amp;engine, proto, getBaseClasses, "getBaseClasses");
    <!--
    fun = engine.newFunction(getBaseClasses);
    fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
    proto->setProperty("getBaseClasses", fun, 
        QScriptValue::SkipInEnumeration);
    -->
                   
    <xsl:for-each select="baseClass[position() != 1 and @specifier='public']">
      <xsl:if test="starts-with(@name , 'R') and rs:isClassScriptable(@name)">

        // properties of secondary base class <xsl:value-of select="@name"/>:
        <xsl:apply-templates select="document(rs:getXmlFile(@name))/unit/class/property" mode="init">
           <xsl:with-param name="overrideClassName" select="$name"/>
        </xsl:apply-templates>

        // methods of secondary base class <xsl:value-of select="@name"/>:
        <xsl:apply-templates select="document(rs:getXmlFile(@name))/unit/class/method[@specifier='public']" mode="init">
           <xsl:with-param name="static" select="false()"/>
           <xsl:with-param name="overrideClassName" select="$name"/>
        </xsl:apply-templates>
      </xsl:if>
    </xsl:for-each>

    // properties:
    <xsl:apply-templates select="property" mode="init" />

    // methods:
    <xsl:apply-templates select="method[@specifier='public']" mode="init" >
       <xsl:with-param name="static" select="false()"/>
    </xsl:apply-templates>

    <xsl:choose>
      <xsl:when test="$sharedPointerSupport">
        engine.setDefaultPrototype(
            qMetaTypeId&lt;<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer" />&gt;(), *proto);
      </xsl:when>
      <xsl:otherwise>
        engine.setDefaultPrototype(
            qMetaTypeId&lt;<xsl:value-of select="$name" />*&gt;(), *proto);

        <xsl:choose>
            <xsl:when test="$isCopyable">
                engine.setDefaultPrototype(qMetaTypeId&lt;
                <xsl:value-of select="$name" />
                &gt; (), *proto);
            </xsl:when>
            <xsl:otherwise>
                <xsl:if test="not($isAbstract)">
                    <xsl:if test="$isQObject">
                        qScriptRegisterMetaType&lt;
                        <xsl:value-of select="$name" />*&gt;(
                        &amp;engine, toScriptValue, fromScriptValue, *proto);
                    </xsl:if>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
    

    QScriptValue ctor = engine.newFunction(createEcma, *proto, 2);
    
    // static methods:
    <xsl:apply-templates select="method[@specifier='public']" mode="init" >
       <xsl:with-param name="static" select="true()"/>
    </xsl:apply-templates>

    // static properties:
    <xsl:apply-templates select="property" mode="init" >
       <xsl:with-param name="static" select="true()"/>
    </xsl:apply-templates>

    // enum values:
    <xsl:apply-templates select="enum/value" mode="init" />

    // enum conversions:
    <xsl:apply-templates select="enum" mode="init" />
        
    // init class:
    engine.globalObject().setProperty("<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer"/>",
    ctor, QScriptValue::SkipInEnumeration);
    
    if( protoCreated ){
       delete proto;
    }
    
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>


<xsl:template name="createAbstract">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>createEcma(QScriptContext* context, QScriptEngine* engine) 
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {
           return REcmaHelper::throwError("Abstract class <xsl:value-of select="$name" />: Cannot be constructed.",
               context); 
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="create">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>createEcma(QScriptContext* context, QScriptEngine* engine) 
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {
    if (context-&gt;thisObject().strictlyEquals(
       engine-&gt;globalObject())) {
       return REcmaHelper::throwError(
       QString::fromLatin1("<xsl:value-of select="$name"/>(): Did you forget to construct with 'new'?"),
           context);
    }

    QScriptValue result;
    <xsl:choose>
        <xsl:when test="constructor/variant">    
            // generate constructor variants:
            <xsl:apply-templates select="constructor/variant" mode="switch" />
        </xsl:when>
        <xsl:otherwise>
            // constructor without variants:
            <xsl:call-template name="constructor_variant">
                <xsl:with-param name="args" select="/.."/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
    {
       return REcmaHelper::throwError(
       QString::fromLatin1("<xsl:value-of select="$name"/>(): no matching constructor found."),
           context);
    }
    
    return result;
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="/unit/class/enum/value" mode="init">
    <xsl:variable name="name" select="ancestor::class/@name"/>

    ctor.setProperty("<xsl:value-of select="@name" />",
    QScriptValue(<xsl:value-of select="$name"/>::<xsl:value-of select="@name"/>),
    QScriptValue::ReadOnly);
</xsl:template>

<xsl:template match="/unit/class/property" mode="init">
    <xsl:param name="overrideClassName" select="ancestor::class/@name"/>
    <xsl:param name="static" select="false()"/>
    
    <xsl:variable name="name" select="$overrideClassName"/>
    <xsl:variable name="methodName" select="@name"/>

    <!-- make sure that we don't duplicate properties from a secondary base class: -->
    <xsl:if test="$overrideClassName=ancestor::class/@name or 
      not(document(rs:getXmlFile($overrideClassName))/unit/class/method[@name=$methodName and @specifier='public'])">
          <xsl:choose>
            <!--
            <xsl:when test="$static=true() and @isStatic='true' and @isConst='true'">
            -->
            <xsl:when test="$static=true() and @isStatic='true'">
            ctor.setProperty("<xsl:value-of select="@name" />",
                qScriptValueFromValue(&amp;engine, <xsl:value-of select="$name" />::<xsl:value-of select="@name" />),
                QScriptValue::SkipInEnumeration | QScriptValue::ReadOnly);
            </xsl:when>
            <xsl:when test="$static=false() and (not(@isStatic) or @isStatic!='true')">
            proto->setProperty("<xsl:value-of select="@name" />", engine.newFunction(
                getSet<xsl:value-of select="rs:capitalize(@name)" />),
                QScriptValue::PropertyGetter
                <xsl:if test="@cppSetter">
                    | QScriptValue::PropertySetter
                </xsl:if>
            );          
            </xsl:when>
          </xsl:choose>
    </xsl:if>
</xsl:template>


<xsl:template match="/unit/class/property">
    <xsl:param name="overrideClassName" select="ancestor::class/@name"/>

    <xsl:if test="not(@isStatic) or @isStatic!='true'">
    
    <xsl:variable name="name" select="$overrideClassName"/>    
    <xsl:variable name="methodName" select="@name"/>
    
    <!-- make sure that we don't duplicate properties from a secondary base class: -->
    <xsl:if test="$overrideClassName=ancestor::class/@name or 
      not(document(rs:getXmlFile($overrideClassName))/unit/class/method[@name=$methodName and @specifier='public'])">

        <xsl:variable name="conversionMethod"
            select="rs:query('conversions.xml', rs:stripReferenceOrPointer(@type), 'toVariant()')" />

        <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>getSet<xsl:value-of select="rs:capitalize(@name)" />
        (QScriptContext* context, QScriptEngine* engine) 
        <xsl:choose>
            <xsl:when test="$mode='h'">
                <xsl:text>;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
        {
        <xsl:value-of select="$name" />* self = getSelf("<xsl:value-of select="@name"/>", context);
        //Q_ASSERT(self!=NULL);
        if (self==NULL) {
            return REcmaHelper::throwError("self is NULL", context);
        }
        <!--
            REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$name" /> &gt;(context-&gt;thisObject());
        <xsl:if test="$hasShell">
            if (self==NULL) {
                <xsl:value-of select="$nameOrShellName" />*
                self = 
                REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
            }
        </xsl:if>
        if(self == NULL){
            return REcmaHelper::throwError("<xsl:value-of select="$name" />.<xsl:value-of select="@name" />(): This object is not a <xsl:value-of select="$name" />",
              context);
        }
        -->

        <xsl:if test="@cppSetter">
            if(context-&gt;argumentCount() == 1){
                <xsl:call-template name="arg">
                    <xsl:with-param name="typeName" select="@type"/>
                    <xsl:with-param name="index" select="'0'"/>
                </xsl:call-template>
                self-&gt;<xsl:value-of select="@cppSetter" />(a0);
            }
        </xsl:if>

        <xsl:value-of select="@type" />
        cppResult = self-&gt;
        <xsl:value-of select="@cppGetter" />();
        QScriptValue result;
        <xsl:call-template name="result">
            <xsl:with-param name="returnType" select="@type"/>
        </xsl:call-template>
        return result;
        }
        </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
    </xsl:if>
</xsl:template>

<xsl:template match="/unit/class/method" mode="init">
    <xsl:param name="static"/>
    <xsl:param name="overrideClassName" select="ancestor::class/@name"/>

    <xsl:variable name="name" select="$overrideClassName"/>
    <xsl:variable name="methodName" select="@name"/>

    <!-- make sure that we don't duplicate methods from a secondary base class: -->
    <xsl:if test="$overrideClassName=ancestor::class/@name or 
      not(document(rs:getXmlFile($overrideClassName))/unit/class/method[@name=$methodName and @specifier='public'])">

        <xsl:choose>
            <xsl:when test="@isStatic='false' and $static=false()">
            REcmaHelper::registerFunction(&amp;engine, proto, <xsl:value-of select="rs:fixFunctionName(@name)" />, "<xsl:value-of select="rs:fixFunctionName(@name)" />");
            <!--
            fun = engine.newFunction(<xsl:value-of select="rs:fixFunctionName(@name)" />);
            fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
            proto->setProperty("<xsl:value-of select="rs:fixFunctionName(@name)" />",
                fun,
                QScriptValue::SkipInEnumeration);
            -->
            </xsl:when>
            <xsl:when test="@isStatic='true' and $static=true()">
            REcmaHelper::registerFunction(&amp;engine, &amp;ctor, <xsl:value-of select="rs:fixFunctionName(@name)" />, "<xsl:value-of select="rs:fixFunctionName(@name)" />");
            <!--
            fun = engine.newFunction(<xsl:value-of select="rs:fixFunctionName(@name)" />);
            fun.setData(QScriptValue(&amp;engine, uint(0xBABE0000)));
            ctor.setProperty("<xsl:value-of select="rs:fixFunctionName(@name)" />",
                fun,
                QScriptValue::SkipInEnumeration);
            -->
            </xsl:when>    
        </xsl:choose>

    </xsl:if>
</xsl:template>

<xsl:template match="/unit/class/method">
    <xsl:param name="overrideClassName" select="ancestor::class/@name"/>
    
    <xsl:variable name="name" select="$overrideClassName"/>
    <xsl:variable name="methodName" select="@name"/>
        
    <!-- make sure that we don't duplicate methods from a secondary base class: -->
    <xsl:if test="$overrideClassName=ancestor::class/@name or 
      not(document(rs:getXmlFile($overrideClassName))/unit/class/method[@name=$methodName and @specifier='public'])">

        <xsl:value-of select="$static"/> QScriptValue
        <xsl:value-of select="$prefix"/><xsl:value-of select="rs:fixFunctionName(@name)" />
        (QScriptContext* context, QScriptEngine* engine) 
        <xsl:choose>
            <xsl:when test="$mode='h'">
                <xsl:text>;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
        {
            //REcmaHelper::functionStart("<xsl:value-of select="$prefix"/><xsl:value-of select="@name" />", context, engine);
            //qDebug() &lt;&lt; "ECMAScript WRAPPER: <xsl:value-of select="$prefix"/><xsl:value-of select="@name" />";
            //QCoreApplication::processEvents();

            QScriptValue result = engine-&gt;undefinedValue();
            <xsl:if test="@isStatic!='true'">
                <xsl:choose>
                  <xsl:when test="@specifier='protected'">
                    // protected function: can only be called from ECMA shell:
                    <xsl:value-of select="$nameOrShellName" />* self = 
                        getSelfShell("<xsl:value-of select="@nameOrShellName"/>", context);
                  </xsl:when>
                  <xsl:otherwise>
                    // public function: can be called from ECMA wrapper of ECMA shell:
                    <xsl:value-of select="$name" />* self = 
                        getSelf("<xsl:value-of select="@name"/>", context);
                  </xsl:otherwise>
                </xsl:choose>

                //Q_ASSERT(self!=NULL);
                if (self==NULL) {
                    return REcmaHelper::throwError("self is NULL", context);
                }
                <!--
                <xsl:value-of select="$nameOrShellName" />*
                self = 
                REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
                -->
                <!--
                qscriptvalue_cast&lt;
                <xsl:value-of select="$nameOrShellName" />*&gt;(context-&gt;thisObject());
                -->
                <!--
                if(self == NULL){
                    return REcmaHelper::throwError("<xsl:value-of select="$name" />.<xsl:value-of select="rs:fixFunctionName(@name)" />(): This object is not a <xsl:value-of select="$name" />",
                      context);
                }
                -->
            </xsl:if>
            
            <xsl:apply-templates select="variant" mode="switch"/>
            {
               return REcmaHelper::throwError("Wrong number/types of arguments for <xsl:value-of select="$name" />.<xsl:value-of select="rs:fixFunctionName(@name)" />().",
                   context);
            }
            //REcmaHelper::functionEnd("<xsl:value-of select="$prefix"/><xsl:value-of select="@name" />", context, engine);
            return result;
        }
        </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>


<xsl:template match="/unit/class/constructor/variant" mode="switch">
    <xsl:call-template name="constructor_variant">
       <xsl:with-param name="args" select="arg"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="constructor_variant">
    <xsl:param name="args" />

    <!--
    <xsl:variable name="isCopyable" select="ancestor-or-self::class/@isCopyable = 'true'"/>
    -->
    <xsl:variable name="isQObject" select="ancestor-or-self::class/@isQObject = 'true'"/>
    <xsl:variable name="name" select="ancestor-or-self::class/@name"/>
    
    <xsl:if test="$args[last()]/@hasDefault='true'">
        <xsl:call-template name="constructor_variant">
            <xsl:with-param name="args" select="$args[position() != last()]"/>
        </xsl:call-template>
    </xsl:if>
    if( context-&gt;argumentCount() ==
        <xsl:value-of select="count($args)" />
        <xsl:for-each select="$args">
            <xsl:if test="@typeName!='QVariant'">
                <xsl:variable name="c"><xsl:value-of select="position()-1"/></xsl:variable>
                &amp;&amp; (
                <xsl:for-each select="rs:getTestFunctions(@typeName)">
                    <xsl:choose>
                      <xsl:when test="@typeName='QVariant'">
                        true
                      </xsl:when>
                      <xsl:otherwise>
                        context-&gt;argument(
                        <xsl:value-of select="$c" />
                        ).<xsl:value-of select="." /> 
                      </xsl:otherwise>
                    </xsl:choose>
                    <xsl:if test="position()!=last()">
                        ||
                    </xsl:if>
                </xsl:for-each>
                ) /* type: <xsl:value-of select="@typeName"/> */
            </xsl:if>
        </xsl:for-each>
    ){
    // prepare arguments:
    <xsl:apply-templates mode="getargs" select="$args" />
    <xsl:variable name="arglist">
        <xsl:apply-templates mode="getlist" select="$args" />
    </xsl:variable>
    // end of arguments

    // call C++ constructor:
    <xsl:choose>
        <xsl:when test="$isCopyable">
            // copyable class:
            <xsl:choose>
                <xsl:when test="$arglist = ''">
                    <xsl:value-of select="$nameOrShellName" />
                    cppResult;
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$nameOrShellName" />
                    cppResult(
                    <xsl:value-of select="$arglist" />
                    );
                </xsl:otherwise>
            </xsl:choose>
            result = engine-&gt;newVariant(
            context-&gt;thisObject(), qVariantFromValue(cppResult));
        </xsl:when>
        <xsl:otherwise>
            // non-copyable class:
            <xsl:choose>
                <xsl:when test="$arglist = ''">
                    <xsl:value-of select="$nameOrShellName" />
                    * cppResult =
                    new
                    <xsl:value-of select="$nameOrShellName" />
                    ();
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$nameOrShellName" />
                    * cppResult =
                    new
                    <xsl:value-of select="$nameOrShellName" />
                    (
                    <xsl:value-of select="$arglist" />
                    );
                </xsl:otherwise>
            </xsl:choose>
            <xsl:choose>
                <xsl:when test="$isQObject">
                    result = engine-&gt;newQObject(context-&gt;thisObject(), cppResult, <xsl:value-of select="$ownership"/>);
                </xsl:when>
                <xsl:otherwise>
                    // TODO: triggers: Warning: QScriptEngine::newVariant(): changing class of non-QScriptObject not supported:
                    result = engine-&gt;newVariant(context-&gt;thisObject(), qVariantFromValue(cppResult));
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:if test="$hasShell='true'">
        cppResult->__qtscript_self = result;
    </xsl:if>
    } else 
</xsl:template>

<xsl:template match="/unit/class/method/variant" mode="switch">
    <xsl:param name="methodPrefix" select="''"/>
    <xsl:call-template name="method_variant">
        <xsl:with-param name="args" select="arg"/>
        <xsl:with-param name="methodPrefix" select="$methodPrefix"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="method_variant">
    <xsl:param name="args" />
    <xsl:param name="methodPrefix" select="''"/>

    <xsl:variable name="name" select="ancestor::class/@name"/>
    <!-- 
    <xsl:choose>
    
        <xsl:when test="@isPureVirtual='true'">
            // pure virtual
        </xsl:when>
        
        <xsl:otherwise> -->


    <xsl:if test="$args[last()]/@hasDefault='true'">
        <xsl:call-template name="method_variant">
            <xsl:with-param name="args" select="$args[position() != last()]"/>
            <xsl:with-param name="methodPrefix" select="$methodPrefix"/>
        </xsl:call-template>
    </xsl:if>
    
    if( context-&gt;argumentCount() ==
    <xsl:value-of select="count($args)" />
    <xsl:for-each select="$args">
        <xsl:variable name="c"><xsl:value-of select="position()-1"/></xsl:variable>
        <xsl:text> &amp;&amp; (</xsl:text>
        <xsl:for-each select="rs:getTestFunctions(@typeName)">
            context-&gt;argument(<xsl:value-of select="$c" />).<xsl:value-of select="." /> 
            <xsl:if test="position()!=last()">
                <xsl:text> || </xsl:text>
            </xsl:if>
        </xsl:for-each>
        ) /* type: <xsl:value-of select="@typeName"/> */
    </xsl:for-each>
    ){
    // prepare arguments:
    <xsl:apply-templates mode="getargs" select="$args" />
    <xsl:variable name="arglist">
        <xsl:apply-templates mode="getlist" select="$args" />
    </xsl:variable>
    // end of arguments

    // call C++ function:
    // return type '<xsl:value-of select="@returnType"/>'
    <xsl:choose>
        <xsl:when test="@returnType = 'RTextData &amp;'">
            // stripped reference:
            <xsl:value-of select="rs:stripReferenceOrPointer(@returnType)" /> cppResult =
        </xsl:when>
        <xsl:when test="not(@returnType = 'void')">
            <xsl:value-of select="@returnType" /> cppResult =
        </xsl:when>
        <xsl:otherwise>
        </xsl:otherwise>
    </xsl:choose>

    <xsl:choose>
       <xsl:when test="../@isStatic='true'">
           <xsl:value-of select="$name"/>::
       </xsl:when>
       <xsl:otherwise>
           <xsl:choose>
             <xsl:when test="$isShell='true'">
               self-&gt;<xsl:value-of select="$name"/>::<xsl:value-of select="$methodPrefix"/>
             </xsl:when>
             <xsl:otherwise>
               self-&gt;<xsl:value-of select="$methodPrefix"/>
             </xsl:otherwise>
           </xsl:choose>
       </xsl:otherwise>
    </xsl:choose>
    <xsl:value-of select="../@cppName" />
    <xsl:choose>
        <xsl:when test="$arglist = ''">
            <xsl:text>();</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>(</xsl:text>
            <xsl:value-of select="$arglist" />
            <xsl:text>);</xsl:text>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:call-template name="result">
        <xsl:with-param name="returnType" select="@returnType"/>
    </xsl:call-template>
    } else


        <!-- 
        </xsl:otherwise>
    </xsl:choose> -->
    
</xsl:template>

<xsl:template name="result">
    <xsl:param name="returnType"/>
    <xsl:if test="not($returnType = 'void')">
        // return type: <xsl:value-of select="$returnType"/>
        <xsl:choose>
            <xsl:when test="rs:isStandardType($returnType)">
                // standard Type
                result = QScriptValue(cppResult);
            </xsl:when>
            <xsl:when test="$returnType = 'RTextData &amp;'">
                result = engine-&gt;newVariant(
                QVariant::fromValue(cppResult));
            </xsl:when>
            <xsl:when test="rs:isReference($returnType)">
                // reference
                result = engine-&gt;newVariant(
                QVariant::fromValue(&amp;cppResult));
            </xsl:when>
            <xsl:when test="rs:isQObject(rs:stripReferenceOrPointer($returnType))">
                // QObject
                result = engine-&gt;newQObject(cppResult, <xsl:value-of select="$ownership"/>);
            </xsl:when>
            <xsl:when test="rs:isPointer($returnType) and rs:isCopyable(rs:stripReferenceOrPointer($returnType))">
                // pointer, copyable 
                result = qScriptValueFromValue(engine, *cppResult);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QSet&lt;') or starts-with($returnType, 'QSet ')">
                // QSet (convert to QVariantList):
                result = REcmaHelper::setToScriptValue(engine, cppResult);

                <!--
                <xsl:value-of select="$returnType"/>::iterator it;
                QVariantList vl;
                for (it=cppResult.begin(); it!=cppResult.end(); it++) {
                    QVariant v;
                    v.setValue(*it);
                    vl.append(v);
                }
                result = qScriptValueFromValue(engine, vl);
                -->
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QPair')">
                // Pair of ...:
                //result = REcmaHelper::pairToScriptValue(engine, cppResult);
                QVariantList vl;
                QVariant v;
                <xsl:choose>
                  <xsl:when test="contains($returnType, '&lt; QVariant')">
                    // first type of pair is variant:
                    if (QString(cppResult.first.typeName())=="RLineweight::Lineweight") {
                        v.setValue((int)cppResult.first.value&lt;RLineweight::Lineweight&gt;());
                    }
                    else {
                        v.setValue(cppResult.first);
                    }
                  </xsl:when>
                  <xsl:otherwise>
                     v.setValue(cppResult.first);
                  </xsl:otherwise>
                </xsl:choose>

                vl.append(v);
                v.setValue(cppResult.second);
                vl.append(v);
                result = qScriptValueFromValue(engine, vl);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QList') and contains($returnType, 'QPair')">
                // List of Pairs of ...:
                result = REcmaHelper::pairListToScriptValue(engine, cppResult);
            </xsl:when>
            <!--
            <xsl:when test="starts-with($returnType, 'QList') and contains($returnType, 'RGraphicsScene')">
                // List of RGraphicsScene:
                result = REcmaHelper::listToScriptValue(engine, cppResult);
            </xsl:when>
            -->
            <xsl:when test="starts-with($returnType, 'QList')">
                // List of ...:
                result = REcmaHelper::listToScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QVector')">
                // Vector of ...:
                result = REcmaHelper::vectorToScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='QVariant'">
                // QVariant:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='RGraphicsView *'">
                // RGraphicsView:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='RGraphicsScene *'">
                // RGraphicsScene:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='RShape *'">
                // RShape:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='REntity *'">
                // REntity:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='RGrid *'">
                // RGrid:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='RSnapRestriction *'">
                // RSnapRestriction:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <!--
            <xsl:when test="$returnType='QList &lt; RVector &gt;'">
                // List of RVector:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='QList &lt; RSpline &gt;'">
                // List of RSpline:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='QList &lt; QKeySequence &gt;'">
                // List of QKeySequence:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='QList &lt; RGraphicsScene * &gt;'">
                // List of RGraphicsScene*:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="$returnType='QList &lt; RGraphicsView * &gt;'">
                // List of RGraphicsView*:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            -->
            <xsl:when test="starts-with($returnType, 'QSharedPointer') and contains($returnType, 'REntityData')">
                // Shared pointer to entity data, cast to best match:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QSharedPointer') and contains($returnType, 'RObject')">
                // Shared pointer to object, cast to best match:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QSharedPointer') and contains($returnType, 'REntity')">
                // Shared pointer to entity, cast to best match:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:when test="starts-with($returnType, 'QSharedPointer') and contains($returnType, 'RShape')">
                // Shared pointer to shape, cast to best match:
                result = REcmaHelper::toScriptValue(engine, cppResult);
            </xsl:when>
            <xsl:otherwise>
                // not standard type nor reference
                result = qScriptValueFromValue(engine, cppResult);
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>

<xsl:template match="arg" mode="getargs">
    <xsl:call-template name="arg">
        <xsl:with-param name="typeName" select="@typeName"/>
        <xsl:with-param name="index" select="position() - 1"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="arg">
    <xsl:param name="typeName"/>
    <xsl:param name="index"/>
    <xsl:variable name="conversionMethod"
        select="rs:query('conversions.xml', rs:stripReferenceOrPointer($typeName), 'toVariant()')" />
    <xsl:variable name="conversionCast"
        select="rs:getConversionCast($typeName)" />
    <xsl:variable name="name" select="ancestor::class/@name"/>

    <xsl:choose>
        <xsl:when test="$conversionMethod = 'toQObject()'">
            // argument isQObject
            <xsl:value-of select="$typeName" />
            a<xsl:value-of select="$index" /> =
            qobject_cast&lt;
            <xsl:value-of select="$typeName" />&gt;
            ( context-&gt;argument(
            <xsl:value-of select="$index" />
            ).
            <xsl:value-of select="$conversionMethod" />
            );
        </xsl:when>
        <xsl:otherwise>
            <xsl:choose>
                <xsl:when test="rs:isStandardType($typeName) and rs:hasDefaultConstructor($typeName)">
                    // argument isStandardType
                    <!--
                    e.g.:
                    int a0 = (int)context->argument(0).conversionMethod();
                    -->
                    <xsl:value-of select="$typeName" />
                    a<xsl:value-of select="$index" /> =
                    (<xsl:value-of select="$typeName" />)
                    <xsl:if test="$conversionCast!=''">
                        <xsl:value-of select="$conversionCast" />
                    </xsl:if>
                    context-&gt;argument( <xsl:value-of select="$index" /> ).
                    <xsl:value-of select="$conversionMethod" />;
                </xsl:when>
                <xsl:when test="rs:isSharedPointer($typeName)">
                    // argument is SharedPointer
                    <xsl:variable name="pointerType">
                        <xsl:value-of select="rs:replace( rs:replace($typeName, 'QSharedPointer &lt;', ''), '&gt;', '')"/>
                    </xsl:variable>
                    <!--
                    e.g. QSharedPointer<RObject> a0 = 
                             QSharedPointer<RObject>(
                                 qscriptvalue_cast <RObject*>(context->argument(0))->clone()
                             );
                    -->

                    <xsl:value-of select="$typeName" /> 
                    a<xsl:value-of select="$index" />;

                    // argument might be a simple pointer:
                    <xsl:value-of select="$pointerType"/>* o<xsl:value-of select="$index" /> = 
                    qscriptvalue_cast &lt;<xsl:value-of select="$pointerType"/>* &gt; (context->argument(<xsl:value-of select="$index" />));

                    if (o<xsl:value-of select="$index" />!=NULL) {
                        a<xsl:value-of select="$index" /> =
                        <xsl:choose>
                        <xsl:when test="contains($typeName, 'RShape')">
                          // always clone shape if we expect a shared pointer (might be a simple object on stack):
                          <xsl:value-of select="$typeName"/>(o<xsl:value-of select="$index" />-&gt;clone());
                        </xsl:when>
                        <xsl:otherwise>
                          // never clone RObject based object:
                          <xsl:value-of select="$typeName"/>(o<xsl:value-of select="$index" />);
                        </xsl:otherwise>
                        </xsl:choose>
                    }
                    else {
                        // qscriptvalue_cast to QSharedPointer&lt;BaseClass&gt; does not work
                        <xsl:value-of select="$typeName" />*
                        p<xsl:value-of select="$index" />;

                        p<xsl:value-of select="$index" /> =
                        qscriptvalue_cast &lt;<xsl:value-of select="$typeName"/>* &gt; (context->argument(<xsl:value-of select="$index" />));

                        if (p<xsl:value-of select="$index" />==NULL) {
                           return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$pointerType" />.", context);                    
                        }

                        a<xsl:value-of select="$index" /> = *p<xsl:value-of select="$index" />;

                           //return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$pointerType" />.",
                           //    context);                    
                    }

                    //<xsl:value-of select="$typeName" /> 
                    //a<xsl:value-of select="$index" /> =
                    //<xsl:value-of select="$typeName"/>(o<xsl:value-of select="$index" />-&gt;clone());
                </xsl:when>
                <xsl:when test="rs:isCopyable($typeName) and rs:hasDefaultConstructor($typeName) and rs:isSimpleClass($typeName)">
                    // argument isCopyable and has default constructor and isSimpleClass 
                    <!--
                    e.g.:
                    RVector* ap0 = qscriptvalue_cast<RVector*>(context->argument(0));
                    if (ap0 == NULL) {
                           return REcmaHelper::throwError("RDocument: Argument 0 is not of type RVector.", context);
                    }
                    RVector a0 = *ap0;
                    -->
                    <xsl:value-of select="$typeName" />*
                    ap<xsl:value-of select="$index" /> =
                    qscriptvalue_cast&lt;
                    <xsl:value-of select="$typeName" />*
                        &gt;(
                        context-&gt;argument(
                        <xsl:value-of select="$index" />
                        )
                    );
                    if (ap<xsl:value-of select="$index" /> == NULL) {
                           return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$typeName" />.",
                               context);                    
                    }
                    <xsl:value-of select="$typeName" /> 
                    a<xsl:value-of select="$index" /> = 
                    *ap<xsl:value-of select="$index" />;
                </xsl:when>
                <xsl:when test="rs:isPointer($typeName)">
                    // argument is pointer
                    <!-- 
                    e.g.:
                    RTransactionListener* a0 = qscriptvalue_cast<RTransactionListener*>(context->argument(0));
                    -->
                    <xsl:value-of select="$typeName" /> a<xsl:value-of select="$index" /> = NULL;

                    a<xsl:value-of select="$index" /> = 
                        REcmaHelper::scriptValueTo&lt;<xsl:value-of select="rs:stripReferenceOrPointer($typeName)" /> &gt;(
                            context-&gt;argument(<xsl:value-of select="$index" />)
                        );
                    <!--
                    // try to use primary inheritance first:
                    a<xsl:value-of select="$index" /> =
                    qscriptvalue_cast&lt;
                    <xsl:value-of select="$typeName" />
                        &gt;(
                        context-&gt;argument(
                        <xsl:value-of select="$index" />
                        )
                    );

                    if (a<xsl:value-of select="$index" />==NULL &amp;&amp; 
                        !context-&gt;argument(<xsl:value-of select="$index" />).isNull()) {

                        // try to convert to all possible inheritance strains if multiple inheritance is used:
                        a<xsl:value-of select="$index" /> = 
                            REcmaHelper::scriptValueTo&lt;<xsl:value-of select="rs:stripReferenceOrPointer($typeName)" /> &gt;(
                                context-&gt;argument(<xsl:value-of select="$index" />)
                            );

                        QScriptValue fBaseClasses = 
                            context-&gt;argument(<xsl:value-of select="$index" />).property("getBaseClasses");
                        QScriptValue baseClasses = 
                            fBaseClasses.call(context-&gt;argument(<xsl:value-of select="$index" />));

                        // skip first base class (primary base class):
                        int i=1;
                        while(true) {
                            QScriptValue baseClass = baseClasses.property(i);
                            if (baseClass.toString().isEmpty()) {
                                break;
                            }

                            //qDebug() &lt;&lt; "base class[" &lt;&lt; i &lt;&lt; "]: " &lt;&lt; baseClass.toString();

                            a<xsl:value-of select="$index" /> =
                            qscriptvalue_cast&lt;
                            <xsl:value-of select="$typeName" />
                                &gt;(
                                context-&gt;argument(
                                <xsl:value-of select="$index" />
                                ).property(
                                    QString("get") + baseClass.toString()
                                ).call(context-&gt;argument(<xsl:value-of select="$index" />))
                            );

                            if (a<xsl:value-of select="$index" />!=NULL) {
                                break;
                            }

                            i++;
                        }

                        if (a<xsl:value-of select="$index" />==NULL) {
                            return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$typeName" /><xsl:value-of select="$typeName" />.", context);                    
                        }
                    }
                    -->
                    if (a<xsl:value-of select="$index" />==NULL &amp;&amp; 
                        !context-&gt;argument(<xsl:value-of select="$index" />).isNull()) {
                        return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$typeName" /><xsl:value-of select="$typeName" />.", context);                    
                    }
                </xsl:when>
                <xsl:when test="rs:isArray($typeName)">
                    // argument isArray
                    <!-- 
                    e.g.:
                    RUcs::Id a0 = qscriptvalue_cast<RUcs::Id>(context->argument(0));
                    -->
                    <xsl:value-of select="$typeName" />
                    a<xsl:value-of select="$index" />;
                    REcmaHelper::fromScriptValue(
                        engine,
                        context-&gt;argument(<xsl:value-of select="$index" />),
                        a<xsl:value-of select="$index" />
                    );
                </xsl:when>
                <xsl:when test="rs:isCopyable($typeName) and rs:hasDefaultConstructor($typeName)">
                    // argument isCopyable or pointer
                    <!-- 
                    e.g.:
                    RUcs::Id a0 = qscriptvalue_cast<RUcs::Id>(context->argument(0));
                    -->
                    <xsl:value-of select="$typeName" />
                    a<xsl:value-of select="$index" /> =
                    qscriptvalue_cast&lt;
                    <xsl:value-of select="$typeName" />
                        &gt;(
                        context-&gt;argument(
                        <xsl:value-of select="$index" />
                        )
                    );
                </xsl:when>
                <xsl:otherwise>
                    // argument is reference
                    <!--
                    e.g.:
                    RObject* ap0 = qscriptvalue_cast<RObject*>(context->argument(0));
                    if(ap0==NULL){
                           return REcmaHelper::throwError("RDocument: Argument 0 is not of type RObject*.", context);                    
                    }
                    RObject& a0 = *ap0;
                    -->
                    <xsl:value-of select="$typeName" />*
                    ap<xsl:value-of select="$index" /> =
                    qscriptvalue_cast&lt;
                    <xsl:value-of select="$typeName" />*
                        &gt;(
                        context-&gt;argument(
                        <xsl:value-of select="$index" />
                        )
                    );
                    if( ap<xsl:value-of select="$index" /> == NULL ){
                           return REcmaHelper::throwError("<xsl:value-of select="$name"/>: Argument <xsl:value-of select="$index" /> is not of type <xsl:value-of select="$typeName" />*.",
                               context);                    
                    }
                    <xsl:value-of select="$typeName" />&amp; a<xsl:value-of select="$index" /> = *ap<xsl:value-of select="$index" />;
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>

</xsl:template>

<xsl:template match="arg" mode="getlist">
    <xsl:variable name="p">
        <xsl:value-of select="position() - 1" />
    </xsl:variable>

    <xsl:text>a</xsl:text>
    <xsl:value-of select="$p" />
    <xsl:if test="not(position() = last())">
        ,
    </xsl:if>
</xsl:template>

<xsl:template name="fromScriptValue">
    <xsl:if test="$isQObject">
        <xsl:value-of select="$static"/> void fromScriptValue(const QScriptValue&amp; value,
        <xsl:value-of select="$name" />*
        &amp;out) {
            QObject* o = value.toQObject();
            out = qobject_cast&lt;
            <xsl:value-of select="$name" />*&gt;(o);
        }
    </xsl:if>
</xsl:template>

<xsl:template name="toScriptValue">
    <xsl:if test="$isQObject">
        <xsl:value-of select="$static"/> QScriptValue toScriptValue(QScriptEngine *engine,
        <xsl:value-of select="$name" />*
        const &amp;in){
            QScriptValue s = engine-&gt;newQObject(in, <xsl:value-of select="$ownership"/>,
            QScriptEngine::PreferExistingWrapperObject);
            /*
            if(s.isNull()){
               REcmaHelper::throwError("This object is null.", engine-&gt;currentContext());
            }
            */
            return s;
        }
    </xsl:if>
</xsl:template>

<xsl:template name="toString">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>toString
    (QScriptContext *context, QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {

    <xsl:value-of select="$name" />* self = getSelf("toString", context);
    <!--
    <xsl:value-of select="$nameOrShellName" />*
    self =
    REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
    -->
    <!--
    qscriptvalue_cast&lt;
    <xsl:value-of select="$name" />*&gt;(context-&gt;thisObject());
    -->
    <!--
    if(self == NULL){
    return REcmaHelper::throwError("<xsl:value-of select="$name" />.toString(): This object is not a <xsl:value-of select="$name" />",
       context);
    }
    -->
    QString result;
    <xsl:choose>
        <xsl:when test="$hasStreamOperator">
            QDebug d(&amp;result);
            if (self!=NULL) {
                d &lt;&lt; *self;
            }
            else {
                d &lt;&lt; "NULL";
            }
        </xsl:when>
        <xsl:otherwise>
            result = QString("<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer" />(0x%1)").arg((unsigned long int)self, 0, 16);
        </xsl:otherwise>
    </xsl:choose>
    return QScriptValue(result);
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="copy">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>copy
    (QScriptContext *context, QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {
        <xsl:value-of select="$name" /> cp = qscriptvalue_cast&lt;<xsl:value-of select="$name" />&gt;(context->thisObject());
        return qScriptValueFromValue(engine, cp);
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="data">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>data
    (QScriptContext *context, QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {

    <xsl:value-of select="$name" />* self = getSelf("data", context);
    return qScriptValueFromValue(engine, self);
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="isNull">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>isNull
    (QScriptContext *context, QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {

    <xsl:value-of select="$name" /><xsl:value-of select="$spsPointer" />* self = REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer" /> &gt;(context-&gt;thisObject());

    //<xsl:value-of select="$name" />* self = getSelf("isNull", context);
    //Q_ASSERT(self!=NULL);
    if (self==NULL) {
        return REcmaHelper::throwError("self is NULL", context);
    }
    return qScriptValueFromValue(engine, self->isNull());
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="destroy">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>destroy(QScriptContext *context, QScriptEngine *engine)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
    {

        <xsl:value-of select="$name" />* self = getSelf("<xsl:value-of select="@name"/>", context);
        //Q_ASSERT(self!=NULL);
        if (self==NULL) {
            return REcmaHelper::throwError("self is NULL", context);
        }
        <!--
        <xsl:value-of select="$nameOrShellName" />*
        self =
        REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
        -->
        <!--
        qscriptvalue_cast&lt;
        <xsl:value-of select="$name" />*&gt;(context-&gt;thisObject());
        -->
        <!--
        if(self == NULL){
            return REcmaHelper::throwError("<xsl:value-of select="$name" />.destroy(): This object is not a <xsl:value-of select="$name" />",
               context);
        }
        -->
    
        delete self;
        context->thisObject().setData(engine->nullValue());
        context->thisObject().prototype().setData(engine->nullValue());
        context->thisObject().setPrototype(engine->nullValue());
        context->thisObject().setScriptClass(NULL);
        return engine->undefinedValue();
    }
    </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="getSelf">
    <xsl:value-of select="$static"/> <xsl:value-of select="$name" />* <xsl:value-of select="$prefix"/>getSelf(const QString&amp; fName, QScriptContext* context)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        {
            <xsl:value-of select="$name" />* self = NULL;

            <xsl:if test="$hasShell">
                // self could be a normal object (e.g. from an UI file) or
                // an ECMA shell object (made from an ECMA script):
                //self = getSelfShell(fName, context);
                <!--
                <xsl:value-of select="$nameOrShellName" />*
                self = REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
                -->
            </xsl:if>

            //if (self==NULL) {
                self = REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$name" /><xsl:value-of select="$spsPointer" /> &gt;(context-&gt;thisObject())
                <xsl:if test="$sharedPointerSupport">
                    ->data()
                </xsl:if>
                ;
            //}

            if (self == NULL){
                // avoid recursion (toString is used by the backtrace):
                if (fName!="toString") {
                    REcmaHelper::throwError(QString("<xsl:value-of select="$name" />.%1(): "
                        "This object is not a <xsl:value-of select="$name" />").arg(fName),
                        context);
                }
                return NULL;
            }

            return self;
        }
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template name="getSelfShell">
    <xsl:value-of select="$static"/> <xsl:value-of select="$nameOrShellName" />* <xsl:value-of select="$prefix"/>getSelfShell(const QString&amp; fName, QScriptContext* context)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        {
          <xsl:choose>
            <xsl:when test="$hasShell">
                <xsl:value-of select="$name" />* selfBase = getSelf(fName, context);
                <xsl:value-of select="$nameOrShellName" />* self = dynamic_cast&lt;<xsl:value-of select="$nameOrShellName" />*&gt;(selfBase);
                //return REcmaHelper::scriptValueTo&lt;<xsl:value-of select="$nameOrShellName" /> &gt;(context-&gt;thisObject());
            if(self == NULL){
                REcmaHelper::throwError(QString("<xsl:value-of select="$name" />.%1(): "
                    "This object is not a <xsl:value-of select="$name" />").arg(fName),
                    context);
            }

            return self;
            </xsl:when>
            <xsl:otherwise>
                REcmaHelper::throwError(QString("<xsl:value-of select="$name" />.getSelfShell(): "
                    "This object has no script shell."),
                    context);
                return NULL;
            </xsl:otherwise>
          </xsl:choose>


        }
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<xsl:template match="/unit/class/enum" mode="init">
    qScriptRegisterMetaType&lt;<xsl:value-of select="$name"/>::<xsl:value-of select="@name"/>&gt;(
        &amp;engine,
        toScriptValueEnum<xsl:value-of select="@name"/>,
        fromScriptValueEnum<xsl:value-of select="@name"/>,
        ctor.property(QString::fromLatin1("prototype"))
    );
</xsl:template>

<xsl:template match="/unit/class/enum">
    <xsl:value-of select="$static"/> QScriptValue <xsl:value-of select="$prefix"/>toScriptValueEnum<xsl:value-of select="@name"/>(QScriptEngine* engine, const <xsl:value-of select="$name"/>::<xsl:value-of select="@name"/>&amp; value)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        {
            return QScriptValue(engine, (int)value);
        }
        </xsl:otherwise>
    </xsl:choose>


    <xsl:value-of select="$static"/> void <xsl:value-of select="$prefix"/>fromScriptValueEnum<xsl:value-of select="@name"/>(const QScriptValue&amp; value, <xsl:value-of select="$name"/>::<xsl:value-of select="@name"/>&amp; out)
    <xsl:choose>
        <xsl:when test="$mode='h'">
            <xsl:text>;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
        {
            out = qvariant_cast&lt;<xsl:value-of select="$name"/>::<xsl:value-of select="@name"/>&gt;(value.toVariant());
        }
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<func:function name="rs:fixFunctionName">
    <xsl:param name="functionName" />
    <func:result>
        <xsl:call-template name="replace_strings">
        <xsl:with-param name="input_text">
            <xsl:value-of select="$functionName"/></xsl:with-param>
        </xsl:call-template>
    </func:result>
</func:function>
<!--  
<func:function name="rs:fixFunctionName">
    <xsl:param name="functionName" />
        <func:result
        select="str:replace(str:replace(
        str:replace($functionName, '+', '_add'), ' ', ''), '=', 'assign'"/>
</func:function>
 -->
 
<func:function name="rs:getTestFunctions">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="document('conversions.xml')/dict/entry[@key = rs:stripReferenceOrPointer($type)]">
            <func:result
                select="com:node-set(document('conversions.xml')/dict/entry[@key = rs:stripReferenceOrPointer($type)]/@testFunction)" />
        </xsl:when>
        <xsl:when test="rs:isQObject(rs:stripReferenceOrPointer($type))">
            <func:result select="com:node-set('isQObject()')"/>
        </xsl:when>
        <xsl:when test="rs:isArray(rs:stripReferenceOrPointer($type))">
            <func:result select="com:node-set('isArray()')"/>
        </xsl:when>
        <xsl:when test="$type='QVariant'">
            <func:result select="document('variantconversion.xml')/list/item/text()"/>
        </xsl:when>
        <xsl:otherwise>
            <func:result select="document('objectconversion.xml')/list/item/text()"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:getConversionCast">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="document('conversions.xml')/dict/entry[@key = rs:stripReferenceOrPointer($type)]/@cast">
            <func:result
                select="concat('(', document('conversions.xml')/dict/entry[@key = rs:stripReferenceOrPointer($type)]/@cast, ')')" />
        </xsl:when>
        <xsl:otherwise>
            <func:result select="''"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isStandardType">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when
            test="document('conversions.xml')/dict/entry
           [@key = rs:stripReferenceOrPointer($type) and not(@value = 'toQObject()') and not(@value = 'toVariant()')]">
            <func:result select="true()" />
        </xsl:when>
        <xsl:otherwise>
            <func:result select="false()" />
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isReference">
    <xsl:param name="type" />
    <func:result select="substring($type, string-length($type))='&amp;'" />
</func:function>

<func:function name="rs:isPointer">
    <xsl:param name="type" />
    <func:result select="substring($type, string-length($type))='*'" />
</func:function>

<!--
  Returns true if the given type is a simple RibbonSoft class, no pointer and no reference and no template class.
-->
<func:function name="rs:isSimpleRType">
    <xsl:param name="type" />
    <func:result select="substring($type, 1, 1)='R' and not(contains($type, '*')) and not(contains($type, '&amp;')) and not(contains($type, '&lt;')) and not(contains($type, ':'))" />
</func:function>

<func:function name="rs:isSimpleClass">
    <xsl:param name="type" />
    <func:result select="not(contains($type, '*')) and not(contains($type, '&amp;')) and not(contains($type, '&lt;')) and not(contains($type, ':')) and not(rs:isStandardType($type)) and $type!='QVariant'" />
</func:function>

<func:function name="rs:stripReferenceOrPointer">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="rs:isReference($type) or rs:isPointer($type)">
            <func:result select="normalize-space(substring($type, 1, string-length($type)-1))" />
        </xsl:when>
        <xsl:otherwise>
            <func:result select="$type" />
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:capitalize">
    <xsl:param name="str" />
    <func:result>
        <xsl:value-of select="rs:toUppercase(substring($str, 1, 1))" />
        <xsl:value-of select="substring($str, 2)" />
    </func:result>
</func:function>

<func:function name="rs:toUppercase">
    <xsl:param name="str" />
    <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
    <func:result>
        <xsl:value-of select="translate($str, $lowercase, $uppercase)" />
    </func:result>
</func:function>

<func:function name="rs:toEcmaName">
    <xsl:param name="str" />
    <xsl:param name="ecma">
      <xsl:choose>
        <xsl:when test="$sharedPointerSupport">
          <xsl:value-of select="'EcmaSharedPointer'"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="'Ecma'"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:param>

    <func:result>
      <xsl:choose>
        <xsl:when test="starts-with($str, 'Qt')">
          <xsl:value-of select="concat(substring($str, 1, 2), $ecma, substring($str, 3))" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat(substring($str, 1, 1), $ecma, substring($str, 2))" />
        </xsl:otherwise>
      </xsl:choose>
    </func:result>
</func:function>

<func:function name="rs:toEcmaShellName">
    <xsl:param name="str" />
    <func:result>
        <xsl:value-of
            select="concat(substring($str, 1, 1), 'EcmaShell', substring($str, 2))" />
    </func:result>
</func:function>

<func:function name="rs:isCopyable">
    <xsl:param name="type" />    
    <xsl:choose>
        <xsl:when test="$type='QVariant'">
            <func:result select="true()" />
        </xsl:when>
        <xsl:when
            test="document('conversions.xml')/dict/entry
           [@key = rs:stripReferenceOrPointer($type) and @value = 'toQObject()']">
            <func:result select="false()" />
        </xsl:when>
        <xsl:when
            test="document('conversions.xml')/dict/entry
           [@key = rs:stripReferenceOrPointer($type) and not(@copyable = 'false')]">
            <func:result select="true()" />
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('src/xml/',$type,'.xml'))">
            <func:result select="document(concat('src/xml/',$type,'.xml'))/unit/class/@isCopyable = 'true'"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('testing/xml/',$type,'.xml'))">
            <func:result select="document(concat('testing/xml/',$type,'.xml'))/unit/class/@isCopyable = 'true'"/>
        </xsl:when>        
        <xsl:otherwise>
           <func:result select="false()"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isSharedPointer">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="starts-with($type, 'QSharedPointer')">
            <func:result select="true()" />
        </xsl:when>
        <xsl:otherwise>
            <func:result select="false()" />
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<!--
<func:function name="rs:isAbstract">
    <xsl:param name="type" />    
    <xsl:choose>
        <xsl:when test="document(concat($scope, '/xml/',$type,'.xml'))">
            <func:result select="document(concat($scope, '/xml/',$type,'.xml'))/unit/class/@isAbstract = 'true'"/>
        </xsl:when>
        <xsl:otherwise>
           <func:result select="false()"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>
-->

<func:function name="rs:hasDefaultConstructor">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when
            test="document('conversions.xml')/dict/entry
           [@key = rs:stripReferenceOrPointer($type) and @defaultConstructor = 'false']">
            <func:result select="false()" />
        </xsl:when>
        <xsl:otherwise>
            <func:result select="true()" />
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isClassScriptable">
    <xsl:param name="type" />    
    <xsl:choose>
        <xsl:when test="rs:isStandardType($type)">
            <func:result select="true()"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('src/xml/',$type,'.xml'))">
            <func:result select="document(concat('src/xml/',$type,'.xml'))/unit/class/@isScriptable = 'true'"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('testing/xml/',$type,'.xml'))">
            <func:result select="document(concat('testing/xml/',$type,'.xml'))/unit/class/@isScriptable = 'true'"/>
        </xsl:when>        
        <xsl:otherwise>
           <func:result select="true()"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isQObject">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="rs:isStandardType($type)">
            <func:result select="false()"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('src/xml/',$type,'.xml'))">
            <func:result select="document(concat('src/xml/',$type,'.xml'))/unit/class/@isQObject = 'true'"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('testing/xml/',$type,'.xml'))">
            <func:result select="document(concat('testing/xml/',$type,'.xml'))/unit/class/@isQObject = 'true'"/>
        </xsl:when>        
        <xsl:otherwise>
            <!-- TODO check if class is QObject -->
            <xsl:variable name="conversionMethod"
                select="rs:query('conversions.xml', rs:stripReferenceOrPointer($type), 'toVariant()')" />            
            <func:result select="$conversionMethod='toQObject()'"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:isArray">
    <xsl:param name="type" />
    <xsl:choose>
        <xsl:when test="starts-with($type, 'QList') or starts-with($type, 'QSet') or $type='QStringList'">
            <func:result select="true()"/>
        </xsl:when>
        <xsl:otherwise>
            <func:result select="false()"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:getXmlFile">
    <xsl:param name="type"/>
    <xsl:choose>
        <xsl:when test="rs:isStandardType($type)">
            <func:result select="''"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('src/xml/',$type,'.xml'))">
            <func:result select="concat('src/xml/',$type,'.xml')"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat('tmp/xml/',$type,'.xml'))">
            <func:result select="concat('tmp/xml/',$type,'.xml')"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat($cwd, '/src/xml/',$type,'.xml'))">
            <func:result select="concat($cwd, '/src/xml/',$type,'.xml')"/>
        </xsl:when>
        <xsl:when test="rs:isSimpleRType($type) and document(concat($cwd, '/testing/xml/',$type,'.xml'))">
            <func:result select="concat($cwd, '/testing/xml/',$type,'.xml')"/>
        </xsl:when>        
        <xsl:otherwise>
           <func:result select="''"/>
        </xsl:otherwise>
    </xsl:choose>
</func:function>

<func:function name="rs:toFunctionName">
    <xsl:param name="type"/>
    <func:result
        select="rs:replace(rs:replace(rs:replace(rs:replace($type, '&lt;','_'), '&gt;',''), ' ',''), ',', '_')" />
</func:function>

<func:function name="rs:getSecondaryBaseClasses">
    <xsl:param name="type"/>
    <xsl:choose>
      <xsl:when test="rs:isSimpleRType($type) and document(concat('src/xml/',$type,'.xml'))">
        <func:result
            select="document(concat('src/xml/',$type,'.xml'))/unit/class/baseClass[position()>1 and @specifier='public']" />
      </xsl:when>
    </xsl:choose>
</func:function>

</xsl:stylesheet>
